#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
语音唤醒检测模块
Voice Wake-up Detection Module

通过串口硬件检测语音唤醒信号
Detects voice wake-up signals through serial hardware
"""

import logging
import threading
import time
from typing import Optional, Callable, Dict, Any
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent))
from utils.serial_comm import SerialCommunicator


class VoiceWakeDetector:
    """
    语音唤醒检测器
    Voice wake-up detector class
    
    负责检测硬件语音唤醒信号并触发相应的回调
    Responsible for detecting hardware voice wake-up signals and triggering callbacks
    """
    
    def __init__(self, config: Dict[str, Any]):
        """
        初始化语音唤醒检测器
        Initialize voice wake-up detector
        
        Args:
            config (Dict[str, Any]): 配置参数 / Configuration parameters
                - serial_port: 串口端口号 / Serial port name
                - baudrate: 波特率 / Baud rate (default: 115200)
                - timeout: 超时时间 / Timeout (default: 1.0)
                - auto_start: 是否自动启动 / Whether to auto start (default: True)
        """
        self.config = config
        self.serial_port = config.get('serial_port', '/dev/myspeech')
        self.baudrate = config.get('baudrate', 115200)
        self.timeout = config.get('timeout', 1.0)
        self.auto_start = config.get('auto_start', True)
        
        # 初始化串口通信器
        self.serial_comm = SerialCommunicator(
            port=self.serial_port,
            baudrate=self.baudrate,
            wake_callback=self._on_wake_detected
        )
        
        # 状态管理
        self.is_running = False
        self.wake_callbacks = []
        self.monitor_thread: Optional[threading.Thread] = None
        
        # 统计信息
        self.wake_count = 0
        self.last_wake_time: Optional[float] = None
        
        # 设置日志
        self.logger = logging.getLogger(__name__)
        
    def add_wake_callback(self, callback: Callable):
        """
        添加唤醒回调函数
        Add wake-up callback function
        
        Args:
            callback (Callable): 唤醒时调用的回调函数 / Callback function when wake-up detected
        """
        if callback not in self.wake_callbacks:
            self.wake_callbacks.append(callback)
            self.logger.info(f"Added wake callback: {callback.__name__}")
            
    def remove_wake_callback(self, callback: Callable):
        """
        移除唤醒回调函数
        Remove wake-up callback function
        
        Args:
            callback (Callable): 要移除的回调函数 / Callback function to remove
        """
        if callback in self.wake_callbacks:
            self.wake_callbacks.remove(callback)
            self.logger.info(f"Removed wake callback: {callback.__name__}")
            
    def start(self) -> bool:
        """
        启动语音唤醒检测
        Start voice wake-up detection
        
        Returns:
            bool: 是否启动成功 / Whether started successfully
        """
        if self.is_running:
            self.logger.warning("Voice wake detector is already running")
            return True
            
        self.logger.info(f"Starting voice wake detector on port: {self.serial_port}")
        
        # 启动串口数据接收
        if not self.serial_comm.start_receiving():
            self.logger.error("Failed to start serial data receiving")
            return False
            
        self.is_running = True
        self.logger.info("Voice wake detector started successfully")
        return True
        
    def stop(self):
        """
        停止语音唤醒检测
        Stop voice wake-up detection
        """
        if not self.is_running:
            return
            
        self.is_running = False
        
        # 停止串口数据接收
        self.serial_comm.stop_receiving()
        
        self.logger.info("Voice wake detector stopped")
        
    def wait_for_wake(self, timeout: Optional[float] = None) -> bool:
        """
        等待唤醒信号（阻塞方式）
        Wait for wake-up signal (blocking)
        
        Args:
            timeout (float, optional): 超时时间 / Timeout in seconds
            
        Returns:
            bool: 是否检测到唤醒信号 / Whether wake-up signal detected
        """
        self.logger.debug(f"[DEBUG] wait_for_wake called with timeout={timeout}")
        if not self.is_running:
            self.logger.warning("[DEBUG] Voice wake detector is not running in wait_for_wake")
            return False
            
        self.logger.debug("[DEBUG] Calling serial_comm.get_wake_signal")
        result = self.serial_comm.get_wake_signal(timeout=timeout)
        self.logger.debug(f"[DEBUG] serial_comm.get_wake_signal returned: {result}")
        return result
        
    def _on_wake_detected(self):
        """
        内部唤醒检测回调
        Internal wake-up detection callback
        """
        current_time = time.time()
        self.wake_count += 1
        self.last_wake_time = current_time
        
        self.logger.info(f"🎯 Voice wake-up detected (count: {self.wake_count}, callbacks: {len(self.wake_callbacks)})")
        
        # 调用所有注册的回调函数
        for i, callback in enumerate(self.wake_callbacks):
            try:
                self.logger.info(f"Calling wake callback {i+1}/{len(self.wake_callbacks)}: {callback.__name__}")
                callback()
                self.logger.info(f"Wake callback {i+1} completed successfully")
            except Exception as e:
                self.logger.error(f"Error in wake callback {i+1} ({callback.__name__}): {e}")
                
    def get_status(self) -> Dict[str, Any]:
        """
        获取检测器状态信息
        Get detector status information
        
        Returns:
            Dict[str, Any]: 状态信息 / Status information
        """
        status = self.serial_comm.get_status()
        return {
            'is_running': self.is_running,
            'serial_connected': status['is_open'] and status['running'],
            'serial_port': self.serial_port,
            'wake_count': self.wake_count,
            'last_wake_time': self.last_wake_time,
            'callback_count': len(self.wake_callbacks),
            'serial_status': status
        }
        
    def reset_statistics(self):
        """
        重置统计信息
        Reset statistics
        """
        self.wake_count = 0
        self.last_wake_time = None
        self.logger.info("Wake-up statistics reset")
        
    def __enter__(self):
        """上下文管理器入口 / Context manager entry"""
        self.start()
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        """上下文管理器出口 / Context manager exit"""
        self.stop()
        
    def __del__(self):
        """析构函数 / Destructor"""
        if hasattr(self, 'is_running') and self.is_running:
            self.stop()